Ext.define('MyDesktop.VideoWindow', {
    extend: 'Ext.ux.desktop.Module',

    uses: [
        'Ext.ux.desktop.Video'
    ],

    id: 'video',
    windowId: 'video-window',

    tipWidth: 160,
    tipHeight: 96,

    init: function () {
        this.launcher = {
            text: 'About Ext JS',
            iconCls: 'video',
            handler: this.createWindow,
            scope: this
        };
    },

    createWindow: function () {
        var me = this, desktop = me.app.getDesktop(),
            win = desktop.getWindow(me.windowId);

        if (!win) {
            win = desktop.createWindow({
                id: me.windowId,
                title: 'About Ext JS',
                width: 740,
                height: 480,
                iconCls: 'video',
                animCollapse: false,
                border: false,
                layout: 'fit',
                items: [
                    {
                        xtype: 'video',
                        id: 'video-player',
                        src: [
                        // browser will pick the format it likes most:
                            {src: '/Video/desktopvideo.mp4', type: 'video/mp4' }
                        ],
                        autobuffer: true,
                        autoplay: true,
                        controls: true,
                        /* default */
                        listeners: {
                            afterrender: function (video) {
                                me.videoEl = video.video.dom;

                                if (video.supported) {
                                    me.tip = new Ext.tip.ToolTip({
                                        anchor: 'bottom',
                                        dismissDelay: 0,
                                        height: me.tipHeight,
                                        width: me.tipWidth,
                                        renderTpl: [
                                            '<canvas width="', me.tipWidth,
                                                  '" height="', me.tipHeight, '">'
                                        ],
                                        renderSelectors: {
                                            body: 'canvas'
                                        },
                                        listeners: {
                                            afterrender: me.onTooltipRender,
                                            show: me.renderPreview,
                                            scope: me
                                        }
                                    }); // tip
                                }
                            }
                        }
                    }
                ],
                listeners: {
                    beforedestroy: function () {
                        me.tip = me.ctx = me.videoEl = null;
                    }
                }
            });
        }

        win.show();

        if (me.tip) {
            me.tip.setTarget(win.taskButton.el);
        }

        return win;
    },

    onTooltipRender: function (tip) {
        // get the canvas 2d context
        var el = tip.body.dom, me = this;
        me.ctx = el.getContext && el.getContext('2d');
    },

    renderPreview: function () {
        var me = this;

        if ((me.tip && !me.tip.isVisible()) || !me.videoEl) {
            return;
        }

        if (me.ctx) {
            try {
                me.ctx.drawImage(me.videoEl, 0, 0, me.tipWidth, me.tipHeight);
            } catch (e) { };
        }

        // 20ms to keep the tooltip video smooth
        Ext.Function.defer(me.renderPreview, 20, me);
    }
});

Ext.define('Ext.ux.desktop.Video', {
    extend: 'Ext.panel.Panel',

    alias: 'widget.video',

    width: '100%',
    height: '100%',
    autoplay: false,
    controls: true,
    bodyStyle: 'background-color:#000;color:#fff',
    html: '',

    initComponent: function () {
        this.callParent();
    },

    afterRender: function () {
        var fallback;

        if (this.fallbackHTML) {
            fallback = this.fallbackHTML;
        } else {
            fallback = "Your browser does not support HTML5 Video. ";

            if (Ext.isChrome) {
                fallback += 'Upgrade Chrome.';
            } else if (Ext.isGecko) {
                fallback += 'Upgrade to Firefox 3.5 or newer.';
            } else {
                var chrome = '<a href="http://www.google.com/chrome">Chrome</a>';
                fallback += 'Please try <a href="http://www.mozilla.com">Firefox</a>';

                if (Ext.isIE) {
                    fallback += ', ' + chrome +
                        ' or <a href="http://www.google.com/chromeframe">Chrome Frame for IE</a>.';
                } else {
                    fallback += ' or ' + chrome + '.';
                }
            }
        }

        // match the video size to the panel dimensions
        var size = this.getSize();

        var cfg = Ext.copyTo({
            tag: 'video',
            width: size.width,
            height: size.height
        },
        this, 'poster,start,loopstart,loopend,playcount,autobuffer,loop');

        // just having the params exist enables them
        if (this.autoplay) {
            cfg.autoplay = 1;
        }
        if (this.controls) {
            cfg.controls = 1;
        }

        // handle multiple sources
        if (Ext.isArray(this.src)) {
            cfg.children = [];

            for (var i = 0, len = this.src.length; i < len; i++) {
                if (!Ext.isObject(this.src[i])) {
                    Ext.Error.raise('The src list passed to "video" must be an array of objects');
                }

                cfg.children.push(
                    Ext.applyIf({ tag: 'source' }, this.src[i])
                );
            }

            cfg.children.push({
                html: fallback
            });

        } else {
            cfg.src = this.src;
            cfg.html = fallback;
        }

        this.video = this.body.createChild(cfg);
        var el = this.video.dom;
        this.supported = (el && el.tagName.toLowerCase() == 'video');
    },

    doComponentLayout: function () {
        var me = this;

        me.callParent(arguments);

        if (me.video)
            me.video.setSize(me.body.getSize());
    },

    onDestroy: function () {
        var video = this.video;
        if (video) {
            var videoDom = video.dom;
            if (videoDom && videoDom.pause) {
                videoDom.pause();
            }
            video.remove();
            this.video = null;
        }

        this.callParent();
    }
});